﻿#region File Header

/* File Name    : FacebookManager.cs
 * Description  : This class contains methods to handle Facebook requests.
 * Log
 * Date             Author              Description
 * 15-Oct-2011      Robin Jome          Created the class
 * 19-Oct-2011      Robin Jome          New Method GetUrl() added
 */

#endregion

#region Namespaces

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using System.Text;


#endregion

namespace FacebookAPI.Base
{
    #region Class

    /// <summary>
    /// This class contains methods to handle Facebook requests.
    /// </summary>
    public class FacebookManager
    {
        #region Get Data

        public FBObject GetData<FBObject>(FacebookRequest request) where FBObject : class
        {
            FBObject fbObject = default(FBObject);
            try
            {
                FacebookRequestHandler handler = new FacebookRequestHandler();
                fbObject = handler.GetData<FBObject>(CreateUri(request));
            }
            catch (WebException ex)
            {
                throw new FacebookException(ex.Message, ex);
            }
            catch (Exception ex)
            {
                throw new FacebookException("Error while reading from Facebook", ex);
            }
            return fbObject;
        }

        #endregion

        #region Common methods

        private Uri CreateUri(FacebookRequest request)
        {
            if (request == null)
                return null;

            StringBuilder uriString = new StringBuilder();
            uriString.Append(ConfigurationManager.AppSettings[Global.GraphBaseUrl]);

            List<string> urlParameters = new List<string>();

            if (!string.IsNullOrEmpty(request.NodeID))
                uriString.AppendFormat("/{0}", request.NodeID);

            if (!string.IsNullOrEmpty(request.EdgeName))
                uriString.AppendFormat("/{0}", request.EdgeName);

            uriString.Append("?");

            if (request.FilterOptions != null)
            {
                if (request.FilterOptions.SearchFields != null)
                {
                    StringBuilder searchFields = new StringBuilder();
                    searchFields.Append("fields=");
                    foreach (var item in request.FilterOptions.SearchFields)
                    {
                        searchFields.Append(GetString(item) + ",");
                    }
                    urlParameters.Add(searchFields.Remove(searchFields.Length - 1, 1).ToString());
                }

                if (request.FilterOptions.Limit != null)
                    uriString.Append("&limit=" + request.FilterOptions.Limit);
            }

            if (!string.IsNullOrEmpty(request.AccessToken))
                urlParameters.Add(string.Format("access_token={0}", request.AccessToken));

            uriString.Append("&").Append(string.Join("&", urlParameters));

            Console.WriteLine(uriString.ToString());
            return new Uri(uriString.ToString());
        }

        private string GetString(SearchField field)
        {
            if (field == null)
            {
                return string.Empty;
            }
            StringBuilder str = new StringBuilder();
            //str.AppendFormat(".fields={0}", field.Field);
            str.Append((field.Limit != null ? ".limit(" + field.Limit.Value.ToString() + ")" : string.Empty));
            if (field.NextLevelFields != null)
            {
                if (field.NextLevelFields.Count > 0)
                {
                    str.Append(".fields(");
                }

                for (int i = 0; i < field.NextLevelFields.Count; i++)
                {
                    str.AppendFormat("{0},", GetString(field.NextLevelFields[i]));
                    if (i == field.NextLevelFields.Count - 1)
                    {
                        str.Remove(str.Length - 1, 1);
                        str.Append(")");
                    }
                }
            }
            return field.Field + str.ToString();
        }

        #endregion
    }

    #endregion
}
